﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace AsmResolver.PE.Win32Resources.String
{
    public class StringResource : IWin32Resource, IEnumerable
    {

        private readonly IDictionary<uint, StringEntry> _entries = new Dictionary<uint, StringEntry>();
        public IDictionary<uint, StringEntry> Entries
        {
            get => _entries;
        }
        public static StringResource FromDirectory(IResourceDirectory rootDirectory)
        {
            var index = ResourceDirectoryHelper.IndexOfResourceDirectoryType(rootDirectory, ResourceType.String);
            if (index == -1)
                return null;
            var stringDirectory = (IResourceDirectory)rootDirectory.Entries[index];

            var result = new StringResource();
            foreach (IResourceDirectory categoryDirectory in stringDirectory.Entries)
            {
                foreach (IResourceData dataEntry in categoryDirectory.Entries)
                {
                    try
                    {
                        result[categoryDirectory.Id] = StringEntry.FromReader(dataEntry.CreateReader(), categoryDirectory.Id, (ushort)dataEntry.Id);
                    }
                    catch
                    {

                    }
                }
            }

            return result;
        }

        public void WriteToDirectory(IResourceDirectory rootDirectory)
        {
            // Find and remove old version directory.
            int index = ResourceDirectoryHelper.IndexOfResourceDirectoryType(rootDirectory, ResourceType.String);

            if (index == -1)
                index = rootDirectory.Entries.Count;
            else
                rootDirectory.Entries.RemoveAt(index);

            var newStringDirectory = new ResourceDirectory(ResourceType.String);

            foreach (var e in _entries)
            {
                newStringDirectory.Entries.Add(
                    new ResourceDirectory(e.Key)
                    {
                        Entries = {
                            new ResourceData(e.Value.CodePage, e.Value) }
                    });
            }

            rootDirectory.Entries.Insert(index, newStringDirectory);
        }

        public IEnumerator GetEnumerator()
        {
            return ((IEnumerable)_entries).GetEnumerator();
        }

        public StringEntry this[uint ID]
        {
            get => _entries[ID];
            set
            {
                if (value is null)
                    _entries.Remove(ID);
                else
                    _entries[ID] = value;
            }
        }
    }
}
